home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / bios.c next >
C/C++ Source or Header  |  2000-01-01  |  34KB  |  1,260 lines

  1. /*
  2.     HLE bios emulation
  3.     ==================
  4.  
  5.     Written by BERO
  6. */
  7.  
  8. #include "fpse.h"
  9.  
  10. #define PSADDR2(addr,base)  ((int)addr-(int)base)
  11. #define PSADDR(addr,base)   (int)(addr?PSADDR2(addr,base):(int)addr)
  12. #define PCADDR(addr,base)   (addr?(addr+base):(void*)addr)
  13.  
  14. static int bios_a0();
  15. static int bios_b0();
  16. static int bios_c0();
  17.  
  18. static char *a0name[] = {
  19.     /* 0x00 */  "open",
  20.     /* 0x01 */ "lseek",
  21.     /* 0x02 */  "read",
  22.     /* 0x03 */  "write",
  23.     /* 0x04 */  "close",
  24.     /* 0x05 */  "ioctl",
  25.     /* 0x06 */  "exit",
  26.     /* 0x07 */  "bios_a0_07",
  27.     /* 0x08 */  "getc",
  28.     /* 0x09 */  "putc",
  29.     /* 0x0a */  "todigit",
  30.     /* 0x0b */  "atof",
  31.     /* 0x0c */  "strtoul",
  32.     /* 0x0d */  "strtol",
  33.     /* 0x0e */  "abs",
  34.     /* 0x0f */  "labs",
  35.     /* 0x10 */  "atoi",
  36.     /* 0x11 */  "atol",
  37.     /* 0x12 */  "atob",
  38.     /* 0x13 */  "setjmp",
  39.     /* 0x14 */  "longjmp",
  40.     /* 0x15 */  "strcat",
  41.     /* 0x16 */  "strncat",
  42.     /* 0x17 */  "strcmp",
  43.     /* 0x18 */  "strncmp",
  44.     /* 0x19 */  "strcpy",
  45.     /* 0x1a */  "strnpy",
  46.     /* 0x1b */  "strlen",
  47.     /* 0x1c */  "index",
  48.     /* 0x1d */  "rindex",
  49.     /* 0x1e */  "strchr",
  50.     /* 0x1f */  "strrchr",
  51.     /* 0x20 */  "strpbrk",
  52.     /* 0x21 */  "strspn",
  53.     /* 0x22 */  "strcspn",
  54.     /* 0x23 */  "strtok",
  55.     /* 0x24 */  "strstr",
  56.     /* 0x25 */  "toupper",
  57.     /* 0x26 */  "tolower",
  58.     /* 0x27 */  "bcopy",
  59.     /* 0x28 */  "bzero",
  60.     /* 0x29 */  "bcmp",
  61.     /* 0x2a */  "memcpy",
  62.     /* 0x2b */  "memset",
  63.     /* 0x2c */  "memmove",
  64.     /* 0x2d */  "memcmp",
  65.     /* 0x2e */  "memchr",
  66.     /* 0x2f */  "rand",
  67.     /* 0x30 */  "srand",
  68.     /* 0x31 */  "qsort",
  69.     /* 0x32 */  "strtod",
  70.     /* 0x33 */  "malloc",
  71.     /* 0x34 */  "free",
  72.     /* 0x35 */  "lsearch",
  73.     /* 0x36 */  "bsearch",
  74.     /* 0x37 */  "calloc",
  75.     /* 0x38 */  "realloc",
  76.     /* 0x39 */  "InitHeap",
  77.     /* 0x3a */  "_exit",
  78.     /* 0x3b */  "getchar",
  79.     /* 0x3c */  "putchar",
  80.     /* 0x3d */  "gets",
  81.     /* 0x3e */  "puts",
  82.     /* 0x3f */  "printf",
  83.     /* 0x40 */  "bios_a0_40",
  84.     /* 0x41 */  "LoadTest",
  85.     /* 0x42 */  "Load",
  86.     /* 0x43 */  "Exec",
  87.     /* 0x44 */  "FlushCache",
  88.     /* 0x45 */  "InstallInterruptHandler",
  89.     /* 0x46 */  "GPU_dw",
  90.     /* 0x47 */  "mem2vram",
  91.     /* 0x48 */  "SendGPU",
  92.     /* 0x49 */  "GPU_cw",
  93.     /* 0x4a */  "GPU_cwb",
  94.     /* 0x4b */  "SendPackets",
  95.     /* 0x4c */  "bios_a0_4c",
  96.     /* 0x4d */  "GetGPUStatus",
  97.     /* 0x4e */  "GPU_sync",
  98.     /* 0x4f */  "bios_a0_4f",
  99.     /* 0x50 */  "bios_a0_50",
  100.     /* 0x51 */  "LoadExec",
  101.     /* 0x52 */  "GetSysSp",
  102.     /* 0x53 */  "bios_a0_53",
  103.     /* 0x54 */  "_96_init",
  104.     /* 0x55 */  "_bu_init",
  105.     /* 0x56 */  "_96_remove",
  106.     /* 0x57 */  "bios_a0_57",
  107.     /* 0x58 */  "bios_a0_58",
  108.     /* 0x59 */  "bios_a0_59",
  109.     /* 0x5a */  "bios_a0_5a",
  110.     /* 0x5b */  "dev_tty_init",
  111.     /* 0x5c */  "dev_tty_open",
  112.     /* 0x5d */  "dev_tty_5d",
  113.     /* 0x5e */  "dev_tty_ioctl",
  114.     /* 0x5f */  "dev_cd_open",
  115.     /* 0x60 */  "dev_cd_read",
  116.     /* 0x61 */  "dev_cd_close",
  117.     /* 0x62 */  "dev_cd_firstfile",
  118.     /* 0x63 */  "dev_cd_nextfile",
  119.     /* 0x64 */  "dev_cd_chdir",
  120.     /* 0x65 */  "dev_card_open",
  121.     /* 0x66 */  "dev_card_read",
  122.     /* 0x67 */  "dev_card_write",
  123.     /* 0x68 */  "dev_card_close",
  124.     /* 0x69 */  "dev_card_firstfile",
  125.     /* 0x6a */  "dev_card_nextfile",
  126.     /* 0x6b */  "dev_card_erase",
  127.     /* 0x6c */  "dev_card_undelete",
  128.     /* 0x6d */  "dev_card_format",
  129.     /* 0x6e */  "dev_card_rename",
  130.     /* 0x6f */  "dev_card_6f",
  131.     /* 0x70 */  "_bu_init(a0_70)",
  132.     /* 0x71 */  "_96_init(a0_71)",
  133.     /* 0x72 */  "_96_remove(a0_72)",
  134.     /* 0x73 */  "bios_a0_73",
  135.     /* 0x74 */  "bios_a0_74",
  136.     /* 0x75 */  "bios_a0_75",
  137.     /* 0x76 */  "bios_a0_76",
  138.     /* 0x77 */  "bios_a0_77",
  139.     /* 0x78 */  "_96_CdSeekL",
  140.     /* 0x79 */  "bios_a0_79",
  141.     /* 0x7a */  "bios_a0_7a",
  142.     /* 0x7b */  "bios_a0_7b",
  143.     /* 0x7c */  "_96_CdGetStatus",
  144.     /* 0x7d */  "bios_a0_7d",
  145.     /* 0x7e */  "_96_CdRead",
  146.     /* 0x7f */  "bios_a0_7f",
  147.     /* 0x80 */  "bios_a0_80",
  148.     /* 0x81 */  "bios_a0_81",
  149.     /* 0x82 */  "bios_a0_82",
  150.     /* 0x83 */  "bios_a0_83",
  151.     /* 0x84 */  "bios_a0_84",
  152.     /* 0x85 */  "_96_CdStop",
  153.     /* 0x86 */  "bios_a0_86",
  154.     /* 0x87 */  "bios_a0_87",
  155.     /* 0x88 */  "bios_a0_88",
  156.     /* 0x89 */  "bios_a0_89",
  157.     /* 0x8a */  "bios_a0_8a",
  158.     /* 0x8b */  "bios_a0_8b",
  159.     /* 0x8c */  "bios_a0_8c",
  160.     /* 0x8d */  "bios_a0_8d",
  161.     /* 0x8e */  "bios_a0_8e",
  162.     /* 0x8f */  "bios_a0_8f",
  163.     /* 0x90 */  "bios_a0_90",
  164.     /* 0x91 */  "bios_a0_91",
  165.     /* 0x92 */  "bios_a0_92",
  166.     /* 0x93 */  "bios_a0_93",
  167.     /* 0x94 */  "bios_a0_94",
  168.     /* 0x95 */  "bios_a0_95",
  169.     /* 0x96 */  "AddCDROMDevice",
  170.     /* 0x97 */  "AddMemCardDevice",
  171.     /* 0x98 */  "DisableKernelIORedirection",
  172.     /* 0x99 */  "EnableKernelIORedirection",
  173.     /* 0x9a */  "bios_a0_9a",
  174.     /* 0x9b */  "bios_a0_9b",
  175.     /* 0x9c */  "SetConf # may be",
  176.     /* 0x9d */  "GetConf # ",
  177.     /* 0x9e */  "bios_a0_9e",
  178.     /* 0x9f */  "SetMem",
  179.     /* 0xa0 */  "_boot",
  180.     /* 0xa1 */  "SystemError",
  181.     /* 0xa2 */  "EnqueueCdIntr",
  182.     /* 0xa3 */  "DequeueCdIntr",
  183.     /* 0xa4 */  "bios_a0_a4",
  184.     /* 0xa5 */  "ReadSector",
  185.     /* 0xa6 */  "get_cd_status",
  186.     /* 0xa7 */  "bufs_cb_0",
  187.     /* 0xa8 */  "bufs_cb_1",
  188.     /* 0xa9 */  "bufs_cb_2",
  189.     /* 0xaa */  "bufs_cb_3",
  190.     /* 0xab */  "_card_info",
  191.     /* 0xac */  "_card_load",
  192.     /* 0xad */  "_card_auto",
  193.     /* 0xae */  "bufs_cb_4",
  194.     /* 0xaf */  "bios_a0_af",
  195.     /* 0xb0 */  "bios_a0_b0",
  196.     /* 0xb1 */  "bios_a0_b1",
  197.     /* 0xb2 */  "do_a_long_jmp",
  198.     /* 0xb3 */  "bios_a0_b3",
  199.     /* 0xb4 */  "bios_a0_b4"
  200. };
  201.  
  202. static char *b0name[] = {
  203.     /* 0x00 */  "SysMalloc",
  204.     /* 0x01 */  "bios_b0_01",
  205.     /* 0x02 */  "bios_b0_02",
  206.     /* 0x03 */  "bios_b0_03",
  207.     /* 0x04 */  "bios_b0_04",
  208.     /* 0x05 */  "bios_b0_05",
  209.     /* 0x06 */  "bios_b0_06",
  210.     /* 0x07 */  "DeliverEvent",
  211.     /* 0x08 */  "OpenEvent",
  212.     /* 0x09 */  "CloseEvent",
  213.     /* 0x0a */  "WaitEvent",
  214.     /* 0x0b */  "TestEvent",
  215.     /* 0x0c */  "EnableEvent",
  216.     /* 0x0d */  "DisableEvent",
  217.     /* 0x0e */  "OpenTh",
  218.     /* 0x0f */  "CloseTh",
  219.     /* 0x10 */  "ChangeTh",
  220.     /* 0x11 */  "bios_b0_11",
  221.     /* 0x12 */  "InitPAD",
  222.     /* 0x13 */  "StartPAD",
  223.     /* 0x14 */  "StopPAD",
  224.     /* 0x15 */  "PAD_init",
  225.     /* 0x16 */  "PAD_dr",
  226.     /* 0x17 */  "ReturnFromException",
  227.     /* 0x18 */  "ResetEntryInt",
  228.     /* 0x19 */  "HookEntryInt",
  229.     /* 0x1a */  "bios_b0_1a",
  230.     /* 0x1b */  "bios_b0_1b",
  231.     /* 0x1c */  "bios_b0_1c",
  232.     /* 0x1d */  "bios_b0_1d",
  233.     /* 0x1e */  "bios_b0_1e",
  234.     /* 0x1f */  "bios_b0_1f",
  235.     /* 0x20 */  "UnDeliverEvent",
  236.     /* 0x21 */  "bios_b0_21",
  237.     /* 0x22 */  "bios_b0_22",
  238.     /* 0x23 */  "bios_b0_23",
  239.     /* 0x24 */  "bios_b0_24",
  240.     /* 0x25 */  "bios_b0_25",
  241.     /* 0x26 */  "bios_b0_26",
  242.     /* 0x27 */  "bios_b0_27",
  243.     /* 0x28 */  "bios_b0_28",
  244.     /* 0x29 */  "bios_b0_29",
  245.     /* 0x2a */  "bios_b0_2a",
  246.     /* 0x2b */  "bios_b0_2b",
  247.     /* 0x2c */  "bios_b0_2c",
  248.     /* 0x2d */  "bios_b0_2d",
  249.     /* 0x2e */  "bios_b0_2e",
  250.     /* 0x2f */  "bios_b0_2f",
  251.     /* 0x30 */  "bios_b0_30",
  252.     /* 0x31 */  "bios_b0_31",
  253.     /* 0x32 */  "open(b0)",
  254.     /* 0x33 */  "lseek(b0)",
  255.     /* 0x34 */  "read(b0)",
  256.     /* 0x35 */  "write(b0)",
  257.     /* 0x36 */  "close(b0)",
  258.     /* 0x37 */  "ioctl(b0)",
  259.     /* 0x38 */  "exit(b0)",
  260.     /* 0x39 */  "bios_b0_39",
  261.     /* 0x3a */  "getc(b0)",
  262.     /* 0x3b */  "putc(b0)",
  263.     /* 0x3c */  "getchar(b0)",
  264.     /* 0x3d */  "putchar(b0)",
  265.     /* 0x3e */  "gets(b0)",
  266.     /* 0x3f */  "puts(b0)",
  267.     /* 0x40 */  "cd",
  268.     /* 0x41 */  "format",
  269.     /* 0x42 */  "firstfile",
  270.     /* 0x43 */  "nextfile",
  271.     /* 0x44 */  "rename",
  272.     /* 0x45 */  "delete",
  273.     /* 0x46 */  "undelete",
  274.     /* 0x47 */  "AddDevice",
  275.     /* 0x48 */  "RemoteDevice",
  276.     /* 0x49 */  "PrintInstalledDevices",
  277.     /* 0x4a */  "InitCARD",
  278.     /* 0x4b */  "StartCARD",
  279.     /* 0x4c */  "StopCARD",
  280.     /* 0x4d */  "bios_b0_4d",
  281.     /* 0x4e */  "_card_write",
  282.     /* 0x4f */  "_card_read",
  283.     /* 0x50 */  "_new_card",
  284.     /* 0x51 */  "Krom2RawAdd",
  285.     /* 0x52 */  "bios_b0_52",
  286.     /* 0x53 */  "bios_b0_53",
  287.     /* 0x54 */  "_get_errno",
  288.     /* 0x55 */  "_get_error",
  289.     /* 0x56 */  "GetC0Table",
  290.     /* 0x57 */  "GetB0Table",
  291.     /* 0x58 */  "_card_chan",
  292.     /* 0x59 */  "bios_b0_59",
  293.     /* 0x5a */  "bios_b0_5a",
  294.     /* 0x5b */  "ChangeClearPAD",
  295.     /* 0x5c */  "_card_status",
  296.     /* 0x5d */  "_card_wait"
  297. };
  298.  
  299. static char *c0name[]={
  300.     /* 0x00 */  "InitRCnt",
  301.     /* 0x01 */  "InitException",
  302.     /* 0x02 */  "SysEnqIntRP",
  303.     /* 0x03 */  "SysDeqIntRP",
  304.     /* 0x04 */  "get_free_EvCB_slot",
  305.     /* 0x05 */  "get_free_TCB_slot",
  306.     /* 0x06 */  "ExceptionHandler",
  307.     /* 0x07 */  "InstallExceptionHandler",
  308.     /* 0x08 */  "SysInitMemory",
  309.     /* 0x09 */  "SysInitKMem",
  310.     /* 0x0a */  "ChangeClearRCnt",
  311.     /* 0x0b */  "SystemError(c0)",
  312.     /* 0x0c */  "InitDefInt",
  313.     /* 0x0d */  "bios_c0_0d",
  314.     /* 0x0e */  "bios_c0_0e",
  315.     /* 0x0f */  "bios_c0_0f",
  316.     /* 0x10 */  "bios_c0_10",
  317.     /* 0x11 */  "bios_c0_11",
  318.     /* 0x12 */  "InstallDevices",
  319.     /* 0x13 */  "FlushStdInOutPut",
  320.     /* 0x14 */  "bios_c0_14",
  321.     /* 0x15 */  "_cdevinput",
  322.     /* 0x16 */  "_cdevscan",
  323.     /* 0x17 */  "_circgetc",
  324.     /* 0x18 */  "_circputc",
  325.     /* 0x19 */  "ioabort",
  326.     /* 0x1a */  "bios_c0_1a",
  327.     /* 0x1b */  "KernelRedirect",
  328.     /* 0x1c */  "PatchAOTable",
  329. };
  330.  
  331. static void *realaddr(int addr) { return (char*)baseaddr(addr)+addr; }
  332.  
  333. #define v0      reg.r[2]
  334. #define v1      reg.r[3]
  335. #define a0      reg.r[4]
  336. #define a1      reg.r[5]
  337. #define a2      reg.r[6]
  338. #define a3      reg.r[7]
  339. #define sp      reg.r[29]
  340. #define stack   ((int*)realaddr(reg.r[29]))
  341.  
  342. int biosprint(int pc)
  343. {
  344.     int ret = 0;
  345.     int no = reg.r[9];
  346.  
  347.     if (verbose) {
  348.         char *name = NULL;
  349.         switch(pc){
  350.         case 0xa0:
  351.             if (no<sizeof(a0name)/sizeof(a0name[0]))
  352.                 name = a0name[no];
  353.             break;
  354.         case 0xb0:
  355.             if (no<sizeof(b0name)/sizeof(b0name[0]))
  356.                 name = b0name[no];
  357.             break;
  358.         case 0xc0:
  359.             if (no<sizeof(c0name)/sizeof(c0name[0]))
  360.                 name = c0name[no];
  361.             break;
  362.         }
  363.         if (name) {
  364.             printf("bios:%s ",name);
  365.         } else {
  366.             printf("bios:%02x,%x",(int)pc,(int)no);
  367.         }
  368.     }
  369.  
  370.     if (!emulate_bios) {
  371.         switch(pc) {
  372.         case 0xa0:
  373.             switch(no) {
  374.             case 0x3f:  // printf
  375.                 PRINTF("%s",(char *)realaddr(a0)); break;
  376.             }
  377.             break;
  378.         case 0xb0:
  379.             switch(no) {
  380.             case 0x08: // OpenEvent
  381.                 PRINTF("(%x,%x,%x,%x)",(int)a0,(int)a1,(int)a2,(int)a3);
  382.                 break;
  383.             case 0x09: //
  384.             case 0x0C: //
  385.             case 0x0D: //
  386.                 PRINTF("(%x)",(int)a0); break;
  387.             case 0x3c:  // getchar
  388.                 v0 = getchar(); PC = reg.r[31]; break;
  389.             case 0x3e:  // gets
  390.             {
  391.                 char *base = (char*)baseaddr(a0);
  392.                 char *ret = gets(base + a0);
  393.                 v0 = PSADDR(ret,base);
  394.                 PC = reg.r[31];
  395.             }
  396.             break;
  397.             case 0x3f: // puts
  398.                 v0 = puts(realaddr(a0)); PC = reg.r[31]; break;
  399.             case 0x3d: // putchar
  400.                 putchar(a0); PC = reg.r[31]; break;
  401.             }
  402.         }
  403.     } else {
  404.         switch (pc) {
  405.         case 0xa0: ret = bios_a0(); break;
  406.         case 0xb0: ret = bios_b0(); break;
  407.         case 0xc0: ret = bios_c0(); break;
  408.         }
  409.         if ((pc!=0xb0) || (no!=0x17)) // ReturnFromException
  410.             PC = reg.r[31];
  411.     }
  412.  
  413.     PRINTF("\n");
  414.     return ret;
  415. }
  416.  
  417. static char *qbase;
  418. static int qsub;
  419.  
  420. static int save_reg[32+3];
  421. static int *jmpbuf;
  422.  
  423. static char *heapbase;
  424.  
  425. static int qcmp(const void *arg0,const void *arg1)
  426. {
  427.     a0 = PSADDR2(arg0,qbase);
  428.     a1 = PSADDR2(arg1,qbase);
  429.     /* qsub‚ðŽÀs */
  430.     return v0;
  431. }
  432.  
  433. typedef struct {
  434.      char   id[6];
  435.      char   fontname[8];
  436.      UINT8  w,h;
  437.      UINT8  type;
  438.      UINT8  ntbl;
  439.      UINT16 codetbl[1];
  440. } FONTXHDR;
  441.  
  442. static FONTXHDR *font;
  443.  
  444. /*
  445.     FONTX   format
  446.     idx     siz
  447.     0       6       "FONTX"
  448.     6       8       font name
  449.     14      1       width
  450.     15      1       height
  451.     16      1       type 0=ANK,1=Japanese
  452. ANK:
  453.     17              font data
  454. Japanese:
  455.     17      1       Number of code table
  456.     18      2       start of code (little endian)
  457.     19      2       end of code
  458.     .
  459.     .
  460.     18+N*4          font data
  461. */
  462. void *Krom2RawAdd(int code)
  463. {
  464.     UINT16 *ptbl = font->codetbl;
  465.     int size = ((font->w+7)/8)*font->h;
  466.     int n=0,i;
  467.  
  468.     for(i=0;i<font->ntbl;i++) {
  469.         if (code>=ptbl[0] && code<=ptbl[1]) {
  470.             return (char*)&font->codetbl[font->ntbl*2] +
  471.                            (code-ptbl[0]+n)*size+2; /* skip */
  472.         }
  473.         n += ptbl[1]-ptbl[0] + 1;
  474.         ptbl+=2;
  475.     }
  476.     return NULL;
  477. }
  478.  
  479. #define strcmpz(a,b)    memcmp(a,b,strlen(b))
  480.  
  481. static char *cd_path="e:";
  482. static char *bu00_path="bu00\\";
  483. static char *bu10_path="bu10\\";
  484. static char *pcdrv_path="";
  485.  
  486. static char *real_path(char *name)
  487. {
  488.     static char buf[256];
  489.  
  490.     if (strcmpz(name,"cdrom:")==0) {
  491.         strcpy(buf,cd_path);
  492.         strcat(buf,name+6);
  493.         { 
  494.             char *p = buf+strlen(buf);
  495.             p[-2]='\0';
  496.             /* "cdrom:filename;1" */
  497.         }
  498.     } else if (strcmpz(name,"bu00:")==0) {
  499.         strcpy(buf,bu00_path);
  500.         strcat(buf,name+5);
  501.     } else if (strcmpz(name,"bu10:")==0) {
  502.         strcpy(buf,bu10_path);
  503.         strcat(buf,name+5);
  504.     } else if (strcmpz(name,"pcdrv:")==0) {
  505.         strcpy(buf,pcdrv_path);
  506.         strcat(buf,name+6);
  507.     } else return NULL;
  508.  
  509.     return buf;
  510. }
  511.  
  512. static int bios_open(char *name,int psxmode)
  513. {
  514. /* psx define
  515. #define   O_RDONLY  1
  516. #define   O_WRONLY  2
  517. #define   O_RDWR         3
  518. #define   O_CREAT        0x200
  519. */
  520.     int mode=O_BINARY;
  521.  
  522.     switch(psxmode&3) {
  523.     case 1: mode|=O_RDONLY; break;
  524.     case 2: mode|=O_WRONLY; break;
  525.     case 3: mode|=O_RDWR; break;
  526.     }
  527.     if (psxmode&0x200) mode|=O_CREAT;
  528.  
  529.     PRINTF("%s",name);
  530.  
  531.     return open(real_path(name),mode);
  532. }
  533.  
  534. #if 0
  535. static void bios_setjmp(int *jmpbuf)
  536. {
  537.     jmpbuf[0] = reg.r[31]; /* ra */
  538.     jmpbuf[1] = reg.r[29]; /* sp */
  539.     jmpbuf[2] = reg.r[28]; /* fp */
  540.     jmpbuf[3] = reg.r[16]; /* s0 */
  541.     jmpbuf[4] = reg.r[17]; /* s1 */
  542.     jmpbuf[5] = reg.r[18]; /* s2 */
  543.     jmpbuf[6] = reg.r[19]; /* s3 */
  544.     jmpbuf[7] = reg.r[20]; /* s4 */
  545.     jmpbuf[8] = reg.r[21]; /* s5 */
  546.     jmpbuf[9] = reg.r[22]; /* s6 */
  547.     jmpbuf[10] = reg.r[23]; /* s7 */
  548.     jmpbuf[11] = reg.r[28]; /* gp */
  549. }
  550. #endif
  551.  
  552. static void bios_longjmp(int *jmpbuf)
  553. {
  554.     reg.r[31] = jmpbuf[0]; /* ra */
  555.     reg.r[29] = jmpbuf[1]; /* sp */
  556.     reg.r[28] = jmpbuf[2]; /* fp */
  557.     reg.r[16] = jmpbuf[3]; /* s0 */
  558.     reg.r[17] = jmpbuf[4]; /* s1 */
  559.     reg.r[18] = jmpbuf[5]; /* s2 */
  560.     reg.r[19] = jmpbuf[6]; /* s3 */
  561.     reg.r[20] = jmpbuf[7]; /* s4 */
  562.     reg.r[21] = jmpbuf[8]; /* s5 */
  563.     reg.r[22] = jmpbuf[9]; /* s6 */
  564.     reg.r[23] = jmpbuf[10]; /* s7 */
  565.     reg.r[28] = jmpbuf[11]; /* gp */
  566. }
  567.  
  568. static int match(char *s1, char *s2)
  569. {
  570.     if (*s1=='.') return 0;
  571.  
  572.     for ( ; ; ) {
  573.         while (*s2 == '*' || *s2 == '?') {
  574.             if (*s2++ == '*')
  575.                 while (*s1 && toupper(*s1) != toupper(*s2)) s1++;
  576.             else
  577.             if (*s1 == 0) return 0;
  578.                      else s1++;
  579.         }
  580.         if (toupper(*s1) != toupper(*s2)) return 0;
  581.         if (*s1 == 0  ) return 1;
  582.         s1++;  s2++;
  583.     }
  584. }
  585.  
  586. /* PSX struct */
  587. struct DIRENTRY {
  588.     char    name[20];
  589.     INT32   attr;
  590.     UINT32  size;
  591.     struct  DIRENTRY *next;
  592.     INT32   head;
  593.     char    system[4];
  594. };
  595.  
  596. static DIR *hdir;
  597. static char pathbuf[256/*MAXPATH*/];
  598. static char matchname[20],*nameptr;
  599.  
  600. struct DIRENTRY* nextfile(struct DIRENTRY *dir)
  601. {
  602.     struct dirent *dirent;
  603.     struct stat statbuf;
  604.  
  605.     if (hdir==NULL) return NULL;
  606.     do {
  607.         dirent = readdir(hdir);
  608.         if (dirent == NULL) {
  609.             closedir(hdir);
  610.             hdir = NULL;
  611.             return NULL;
  612.         }
  613. //   printf("%s %s\n",dirent->d_name,matchname);
  614.     } while(!match(dirent->d_name,matchname));
  615.  
  616. //  printf("match");
  617.  
  618.     strcpy(dir->name,dirent->d_name);
  619.     strcpy(nameptr,dirent->d_name);
  620.     stat(pathbuf,&statbuf);
  621.     dir->size = statbuf.st_size;
  622.  
  623.     return dir;
  624. }
  625.  
  626. #define   PATH_DELIMITER '\\'
  627.  
  628. struct DIRENTRY* firstfile(char *path,struct DIRENTRY *dir)
  629. {
  630.     char *p,*matchpath;
  631.  
  632. //  printf("path;%s\n",path);
  633.  
  634.     strcpy(pathbuf,real_path(path));
  635.     p = strrchr(pathbuf,PATH_DELIMITER);
  636.     if (p) {
  637.         *p=0;
  638.         matchpath = pathbuf;
  639.         nameptr = p+1;
  640.     } else {
  641.         matchpath = ".";
  642.         nameptr = pathbuf;
  643.     }
  644.     strcpy(matchname,nameptr);
  645.  
  646. //  printf("%s %s:\n",matchpath,matchname);
  647.  
  648.     if (hdir) {
  649.         closedir(hdir);
  650.     }
  651.     hdir = opendir(matchpath);
  652.  
  653.     if (hdir==NULL) return NULL;
  654.  
  655.     if (p) {
  656.         *p = PATH_DELIMITER;
  657.     }
  658.  
  659.     return nextfile(dir);
  660. }
  661.  
  662. static char *padbuf1,*padbuf2;
  663. static int padbuf1len,padbuf2len;
  664. static int *padbuf;
  665.  
  666. static void pad_update(void)
  667. {
  668.     int pad1,pad2;
  669.  
  670.     pad1 = 0xFFFF; // JOY_Poll(0);
  671.     pad2 = 0xFFFF; // JOY_Poll(1);
  672.     if (padbuf) *padbuf = (pad1 | (pad2<<16));
  673.     if (padbuf1) {
  674.         padbuf1[0] = 0;
  675.         padbuf1[1] = 0x41;
  676.         padbuf1[2] = pad1 >> 8;
  677.         padbuf1[3] = pad1;
  678.      
  679.         padbuf2[0] = 0;
  680.         padbuf2[1] = 0x41;
  681.         padbuf2[2] = pad2>>8;
  682.         padbuf2[3] = pad2;
  683.     }
  684. }
  685.  
  686. static int bios_b0()
  687. {
  688.     switch(reg.r[9]) {
  689.     case 0x12:  /* InitPAD */
  690.         padbuf1 = realaddr(a0);
  691.         padbuf1len = a1;
  692.         padbuf2 = realaddr(a2);
  693.         padbuf2len = a3;
  694.         break;
  695.     case 0x13:  /* StartPAD */
  696.         hw_write16(0x1f801074,hw_read16(0x1f801074)|1); /* Vsync Interrupt enable */
  697.         SR |= 0x401; /* interrupt enable */
  698.         break;
  699.     case 0x14:  /* StopPAD */
  700.         break;
  701.     case 0x15:  /* PAD_init */
  702.         padbuf = realaddr(a1);
  703.         *padbuf = -1;
  704.         hw_write16(0x1f801074,hw_read16(0x1f801074)|1); /* Vsync Interrupt enable */
  705.         SR |= 0x401; /* interrupt enable */
  706.         break;
  707.     case 0x16:  /* PAD_dr */
  708.         break;
  709.     case 0x17:  /* ReturnFromException */
  710.         SR = (SR & ~0xf)| ((SR>>2)&0xf);
  711.         /* ƒŒƒWƒXƒ^‚ð—áŠO”­¶Žž‚É–ß‚· */
  712.         memcpy(reg.r,save_reg,sizeof(save_reg));
  713.         PC = EPC;
  714.         break;
  715.     case 0x19:  /* HookEntryInt */
  716.         jmpbuf = realaddr(a0);
  717.         break;
  718.     case 0x32:  /* open */
  719.         v0 = bios_open(realaddr(a0),a1);     break;
  720.     case 0x33:  /* lseek */
  721.         v0 = lseek(a0,a1,a2); break;
  722.     case 0x34:  /* read */
  723.         printf("%d %x %d",(int)a0,(int)a1,(int)a2);
  724.         v0 = read(a0,realaddr(a1),a2);  break;
  725.     case 0x35:  /* write */
  726.         v0 = write(a0,realaddr(a1),a2); break;
  727.     case 0x36:  /* close */
  728.         v0 = close(a0);  break;
  729.     case 0x37:  /* ioctl */
  730.     case 0x38:  /* exit */
  731.     case 0x39:  /* ?? */
  732.     case 0x3a:  /* getc */
  733.     case 0x3b:  /* putc */
  734.         return -1;
  735.     case 0x3c:  /* getchar */
  736.         v0 = getchar(); break;
  737.     case 0x3d:  /* putchar */
  738.         v0 = putchar(a0); break;
  739.     case 0x3e:  /* gets */
  740.         {
  741.             char *base = (char*)baseaddr(a0);
  742.             char *ret = gets(base + a0);
  743.             v0 = PSADDR(ret,base);
  744.         }
  745.         break;
  746.     case 0x3f:  /* puts */
  747.         v0 = puts(realaddr(a0)); break;
  748.     case 0x42:  /* 0x42 firstfile */
  749.         {
  750.             int t = (int)firstfile((char *)realaddr(a0),
  751.                                    (struct DIRENTRY *)realaddr(a1));
  752.             if (t) t=a1;
  753.             v0 = t;
  754.         }
  755.         break;
  756.     case 0x43:  /* 0x43 nextfile */
  757.         {
  758.             int t = (int)nextfile((struct DIRENTRY *)realaddr(a0));
  759.             if (t) t=a0;
  760.             v0 = t;
  761.         }
  762.         break;
  763.     case 0x51:  /* Krom2RawAdd */
  764.         {
  765.             void *ret = Krom2RawAdd(a0);
  766.             v0 = PSADDR(ret,rom-0xbfc00000);
  767.         }
  768.         break;
  769.     default:
  770.         /* unsupport */
  771.         return -1;
  772.     }
  773.  
  774.     return 0;
  775. }
  776.  
  777. static int bios_c0()
  778. {
  779.     switch(reg.r[9]) {
  780.     default:
  781.         /* unsupport */
  782.         return -1;
  783.     }
  784.     return 0;
  785. }
  786.  
  787. static int bios_a0()
  788. {
  789.      switch(reg.r[9]) {
  790.      case 0x00:     /* open */
  791.           v0 = bios_open(realaddr(a0),a1);   break;
  792.      case 0x01:     /* lseek */
  793.           v0 = lseek(a0,a1,a2);    break;
  794.      case 0x02:     /* read */
  795.           printf("%d %x %d",(int)a0,(int)a1,(int)a2);
  796.           v0 = read(a0,realaddr(a1),a2);     break;
  797.      case 0x03:     /* write */
  798.           v0 = write(a0,realaddr(a1),a2);    break;
  799.      case 0x04:     /* close */
  800.           v0 = close(a0);     break;
  801.  
  802.      case 0x05:     /* ioctl */
  803.      case 0x06:     /* exit */
  804.      case 0x07:     /* ?? */
  805.      case 0x08:     /* getc */
  806.      case 0x09:     /* putc */
  807.           return -1;
  808.  
  809.      case 0x0a:     /* todigit */
  810.           v0 = a0-'0';   break;
  811.      case 0x0b:     /* atof */
  812.           { union { double d; int lo,hi; } t;
  813.                t.d = atof(realaddr(a0));
  814.                v0 = t.lo;
  815.                v1 = t.hi;
  816.           }
  817.           break;
  818.      case 0x0c:     /* strtoul */
  819.           { char *base = baseaddr(a0);
  820.           char *endp;
  821.           v0 = strtoul(base+a0,&endp,a2);
  822.           if (a1) a1 = PSADDR2(endp,base);
  823.           }
  824.           break;
  825.      case 0x0d:     /* strtol */
  826.           { char *base = baseaddr(a0);
  827.           char *endp;
  828.           v0 = strtol(base+a0,&endp,a2);
  829.           if (a1) a1 = PSADDR2(endp,base);
  830.           }
  831.           break;
  832.      case 0x0e:     /* abs */
  833.      case 0x0f:     /* labs */
  834.           v0 = (a0>=0)?a0:-a0; break;
  835.      case 0x10:     /* atoi */
  836.      case 0x11:     /* atol */
  837.           v0 = atoi(realaddr(a0)); break;
  838.      case 0x12:     /* atob */
  839.           return -1;
  840.  
  841.      case 0x13:     /* setjmp */
  842.           { int *jmpbuf=realaddr(a0);
  843.           jmpbuf[0] = reg.r[31]; /* ra */
  844.           jmpbuf[1] = reg.r[29]; /* sp */
  845.           jmpbuf[2] = reg.r[28]; /* fp */
  846.           jmpbuf[3] = reg.r[16]; /* s0 */
  847.           jmpbuf[4] = reg.r[17]; /* s1 */
  848.           jmpbuf[5] = reg.r[18]; /* s2 */
  849.           jmpbuf[6] = reg.r[19]; /* s3 */
  850.           jmpbuf[7] = reg.r[20]; /* s4 */
  851.           jmpbuf[8] = reg.r[21]; /* s5 */
  852.           jmpbuf[9] = reg.r[22]; /* s6 */
  853.           jmpbuf[10] = reg.r[23]; /* s7 */
  854.           jmpbuf[11] = reg.r[28]; /* gp */
  855.           }
  856.           v0 = 0;
  857.           break;
  858.      case 0x14:     /* longjmp */
  859.           { int *jmpbuf=realaddr(a0);
  860.           reg.r[31] = jmpbuf[0]; /* ra */
  861.           reg.r[29] = jmpbuf[1]; /* sp */
  862.           reg.r[28] = jmpbuf[2]; /* fp */
  863.           reg.r[16] = jmpbuf[3]; /* s0 */
  864.           reg.r[17] = jmpbuf[4]; /* s1 */
  865.           reg.r[18] = jmpbuf[5]; /* s2 */
  866.           reg.r[19] = jmpbuf[6]; /* s3 */
  867.           reg.r[20] = jmpbuf[7]; /* s4 */
  868.           reg.r[21] = jmpbuf[8]; /* s5 */
  869.           reg.r[22] = jmpbuf[9]; /* s6 */
  870.           reg.r[23] = jmpbuf[10]; /* s7 */
  871.           reg.r[28] = jmpbuf[11]; /* gp */
  872.           }
  873.           v0 = a1;
  874.           break;
  875.      case 0x15:     /* strcat */
  876.           v0 = a0; strcat(realaddr(a0),realaddr(a1));  break;
  877.      case 0x16:     /* strncat */
  878.           v0 = a0; strncat(realaddr(a0),realaddr(a1),a2);   break;
  879.      case 0x17:     /* strcat */
  880.           v0 = strcmp(realaddr(a0),realaddr(a1)); break;
  881.      case 0x18:     /* strncmp */
  882.           v0 = strncmp(realaddr(a0),realaddr(a1),a2);  break;
  883.      case 0x19:     /* strcpy */
  884.           v0 = a0; strcpy(realaddr(a0),realaddr(a1));  break;
  885.      case 0x1a:     /* strncpy */
  886.           v0 = a0; strncpy(realaddr(a0),realaddr(a1),a2);   break;
  887.      case 0x1b:     /* strlen */
  888.           v0 = strlen(realaddr(a0));    break;
  889.      case 0x1c:     /* index */
  890.      case 0x1e:     /* strchr */
  891.           { char *base = baseaddr(a0);
  892.           char *ret = strchr(base + a0,a1);
  893.           v0 = PSADDR(ret,base);
  894.           }
  895.           break;
  896.      case 0x1d:     /* rindex */
  897.      case 0x1f:     /* strrchr */
  898.           { char *base = baseaddr(a0);
  899.           char *ret = strrchr(base + a0,a1);
  900.           v0 = PSADDR(ret,base);
  901.           }
  902.           break;
  903.      case 0x20:     /* strpbrk */
  904.           { char *base = baseaddr(a0);
  905.           char *ret = strpbrk(base + a0,realaddr(a1));
  906.           v0 = PSADDR(ret,base);
  907.           }
  908.           break;
  909.      case 0x21:     /* strspn */
  910.           v0 = strspn(realaddr(a0),realaddr(a1)); break;
  911.      case 0x22:     /* strcspn */
  912.           v0 = strcspn(realaddr(a0),realaddr(a1));     break;
  913.      case 0x23:     /* strtok */
  914.           { char *base = baseaddr(a0);
  915.           char *ret = strtok(base + a0,a1?realaddr(a1):(char*)a1);
  916.           v0 = PSADDR(ret,base);
  917.           }
  918.           break;
  919.      case 0x24:     /* strstr */
  920.           { char *base = baseaddr(a0);
  921.           char *ret = strstr(base + a0,realaddr(a1));
  922.           v0 = PSADDR(ret,base);
  923.           }
  924.           break;
  925.      case 0x25:     /* toupper */
  926.           v0 = toupper(a0);   break;
  927.      case 0x26:     /* tolower */
  928.           v0 = tolower(a0);   break;
  929.      case 0x27:     /* bcopy */
  930.           memcpy(realaddr(a1),realaddr(a0),a2);   break;
  931.      case 0x28:     /* bzero */
  932.           memset(realaddr(a0),0,a1);    break;
  933.      case 0x29:     /* bcmp */
  934.           v0 = memcmp(realaddr(a0),realaddr(a1),a2);   break;
  935.      case 0x2a:     /* memcpy */
  936.           v0 = a0; memcpy(realaddr(a0),realaddr(a1),a2);    break;
  937.      case 0x2b:     /* memset */
  938.           v0 = a0; memset(realaddr(a0),a1,a2);    break;
  939.      case 0x2c:     /* memmove */
  940.           v0 = a0; memmove(realaddr(a0),realaddr(a1),a2);   break;
  941.      case 0x2d:     /* memcmp */
  942.           v0 = memcmp(realaddr(a0),realaddr(a1),a2);   break;
  943.      case 0x2e:     /* memchr */
  944.           { char *base = baseaddr(a0);
  945.           char *ret = memchr(base + a0,a1,a2);
  946.           v0 = PSADDR(ret,base);
  947.           }
  948.           break;
  949.      case 0x2f:     /* rand */
  950.           v0 = rand(); break;
  951.      case 0x30:     /* srand */
  952.           srand(a0);     break;
  953.      case 0x31:     /* qsort */
  954.           qbase = baseaddr(a0);
  955.           qsub = a3;
  956.           qsort(qbase + a0,a1,a2,qcmp);
  957.           break;
  958.      case 0x32:     /* strtod */
  959.           { char *base = baseaddr(a0);
  960.           char *endp;
  961.           union { double d; int lo,hi; } t;
  962.           t.d = strtod(base+a0,&endp);
  963.           v0 = t.lo;
  964.           v1 = t.hi;
  965.           if (a1) a1 = PSADDR2(endp,base);
  966.           }
  967.           break;
  968.      case 0x33:     /* malloc */
  969.           {
  970.           char *ret = bios_malloc(a0);
  971.           v0 = PSADDR(ret,heapbase);
  972.           }
  973.           break;
  974.      case 0x34:     /* free */
  975.           bios_free(PCADDR(a0,heapbase));
  976.           break;
  977.      case 0x35:     /* lsearch */
  978.           return -1;
  979. /*
  980.           qbase = baseaddr(a0);
  981.           qsub = stack[4];
  982.           {
  983.           char *ret = lsearch(qbase+a0,qbase+a1,realaddr(a2),a3,qcmp);
  984.           v0 = PSADDR(ret,qbase);
  985.           }
  986.           break;
  987. */
  988.      case 0x36:     /* bsearch */
  989.           qbase = baseaddr(a0);
  990.           qsub = stack[4];
  991.           {
  992.           char *ret = bsearch(qbase+a0,qbase+a1,a2,a3,qcmp);
  993.           v0 = PSADDR(ret,qbase);
  994.           }
  995.           break;
  996.      case 0x37:     /* calloc */
  997.           {
  998.           char *ret = bios_calloc(a0,a1);
  999.           v0 = PSADDR(ret,heapbase);
  1000.           }
  1001.           break;
  1002.      case 0x38:     /* realloc */
  1003.           {
  1004.           char *ret = bios_realloc(PCADDR(a0,heapbase),a1);
  1005.           v0 = PSADDR(ret,heapbase);
  1006.           }
  1007.           break;
  1008.      case 0x39:     /* InitHeap */
  1009.           heapbase = baseaddr(a0);
  1010.           bios_InitHeap(heapbase + a0,a1);
  1011.           break;
  1012.      case 0x3a:     /* _exit */
  1013.           return -1;
  1014.      case 0x3b:     /* getchar */
  1015.           v0 = getchar();     break;
  1016.      case 0x3c:     /* putchar */
  1017.           v0 = putchar(a0);   break;
  1018.      case 0x3d:     /* gets */
  1019.           { char *base = (char*)baseaddr(a0);
  1020.           char *ret = gets(base + a0);
  1021.           v0 = PSADDR(ret,base);
  1022.           }
  1023.           break;
  1024.      case 0x3e:     /* puts */
  1025.           v0 = puts(realaddr(a0)); break;
  1026.      case 0x3f:     /* printf */
  1027.           /* ‰¼ */
  1028.           {char *s = realaddr(a0);
  1029.  
  1030. //        if (strstr(s,"%s")) {
  1031. //             v0 = printf("%s",s);
  1032. //        } else {
  1033.  
  1034.                long *ptr = realaddr(sp);
  1035.                ptr[1] = a1;
  1036.                ptr[2] = a2;
  1037.                ptr[3] = a3;
  1038. #ifdef __WATCOMC__
  1039.                v0 = vprintf(s,(char*)(ptr+1));
  1040. #else
  1041.                v0 = vprintf(s,*((va_list*)(ptr+1)));
  1042. #endif
  1043. //        }
  1044.           }
  1045.           break;
  1046.  
  1047.      case 0x46:     /* GPU_dw */
  1048.        {
  1049.           int size;
  1050.           long *ptr;
  1051.           GP0_Write(0xa0000000);
  1052.           GP0_Write((a1<<16)|(a0&0xffff));
  1053.           GP0_Write((a3<<16)|(a2&0xffff));
  1054.           size = (a2*a3+1)/2;
  1055.           ptr = realaddr(stack[4]);
  1056.           do {
  1057.                GP0_Write(*ptr++);
  1058.           } while(--size);
  1059.        }
  1060.           break;
  1061.      case 0x47:     /* mem2vram */
  1062.        {
  1063.           int size;
  1064.           PRINTF("%d %d %d %d %x",(int)a0,(int)a1,(int)a2,(int)a3,(int)stack[4]);
  1065.           GP0_Write(0xa0000000);
  1066.           GP0_Write((a1<<16)|(a0&0xffff));
  1067.           GP0_Write((a3<<16)|(a2&0xffff));
  1068.           size = (a2*a3+1)/2;
  1069.           GP1_Write(0x04000002);
  1070.           hw_write32(0x1f8010f4,0);
  1071.           hw_write32(0x1f8010f0,hw_read32(0x1f8010f0)|0x800);
  1072.           hw_write32(0x1f8010a0,stack[4]);
  1073.           hw_write32(0x1f8010a4,((size/16)<<16)|16);
  1074.           hw_write32(0x1f8010a8,0x01000201);
  1075.        }
  1076.           break;
  1077.      case 0x48:     /* SendGPU */
  1078.           GP1_Write(a0);
  1079.           break;
  1080.      case 0x49:     /* GPU_cw */
  1081.           GP0_Write(a0);
  1082.           break;
  1083.      case 0x4a:     /* GPU_cwb */
  1084.        {
  1085.           long *ptr = realaddr(a0);
  1086.           int size = a1;
  1087.           while(size--) {
  1088.                GP0_Write(*ptr++);
  1089.           }
  1090.        }
  1091.           break;
  1092.      case 0x4b:     /* SendPackets */
  1093.           GP1_Write(0x04000002);
  1094.           hw_write32(0x1f8010f4,0);
  1095.           hw_write32(0x1f8010f0,hw_read32(0x1f8010f0)|0x800);
  1096.           hw_write32(0x1f8010a0,a0);
  1097.           hw_write32(0x1f8010a4,0);
  1098.           hw_write32(0x1f8010a8,0x010000401);
  1099.           break;
  1100.      case 0x4c:     /* ??? */
  1101.           hw_write32(0x1f8010a8,0x00000401);
  1102.           GP0_Write(0x0400000);
  1103.           GP0_Write(0x0200000);
  1104.           GP0_Write(0x0100000);
  1105.           break;
  1106.      case 0x4d:     /* GetGPUStatus */
  1107.           v0 = GP1_Read();
  1108.           break;
  1109.      case 0x4e:     /* GPU_sync */
  1110.           break;
  1111.      default:
  1112.           /* unsupport */
  1113.           return -1;
  1114.      }
  1115.      return 0;
  1116. }
  1117.  
  1118. #if 0
  1119. int bios_printf(char *fmt,int *arg)
  1120. {
  1121.      int ch;
  1122.      static char decimal = '.';
  1123.  
  1124.      for(cnt=0;;) {
  1125.           while((ch = *fmt++) && ch!='%') { putchar(ch); cnt++; }
  1126.           if (ch=='\0') break;
  1127.      rflag:
  1128.           switch(*fmt++) {
  1129.           case ' ': if (!sign) sign=' '; goto rflag;
  1130.           case '#': flags |= ALT; goto rflag;
  1131.           case '*':
  1132.           case '-': flags |= LADJUST; goto rflag;
  1133.           case '+': sign = '+'; goto rflag;
  1134.           case '.': if (*fmt=='*') {}
  1135.           case '0':
  1136.           case '1':case '2':case '3':case '4':
  1137.           case '5':case '6':case '7':case '8':case '9':
  1138.           case 'L': flags |= LONGDBL; goto rflag;
  1139.           case 'h': flags |= SHORTINT; goto rflag;
  1140.           case 'l': if (flags&LONGINT) flags |= LONGDBL; else flags = LONGINT;
  1141.                goto rflag;
  1142.           case 'q':
  1143.           case 'c':
  1144.           case 'D': flags |= LONGINT;
  1145.           case 'd':
  1146.           case 'i':
  1147.           case 'E':
  1148.           case 'e':
  1149.           case 'f':
  1150.           case 'g':
  1151.           case 'G':
  1152.           case 'n':
  1153.           case 'O':
  1154.           case 'o':
  1155.           case 'p':
  1156.           case 's':
  1157.           case 'U': flags |= LONGINT;
  1158.           case 'u': 
  1159.           case 'X':
  1160.           case 'x':
  1161.           
  1162.           }
  1163.      }
  1164. }
  1165. #endif
  1166.  
  1167. int interrupt_handler()
  1168. {
  1169.      int intr;
  1170.  
  1171.      intr = hw_read16(0x1f801070) & hw_read16(0x1f801074); /* int reg & mask */
  1172.      if (intr&1) { /* VSync interrupt */
  1173.           pad_update();
  1174.      }
  1175.      hw_write16(0x1f801070,0);
  1176.         hw_write32(0x1F8010F4,hw_read32(0x1F8010F4));
  1177.      return 0;
  1178. }
  1179.  
  1180. int exception_handler()
  1181. {
  1182.      if (!emulate_bios) return 0;
  1183.      switch((CAUSE&0x3c)>>2) {
  1184.      case E_Int:
  1185.           /* ƒŒƒWƒXƒ^•Û‘¶ */
  1186.           memcpy(save_reg,reg.r,sizeof(save_reg));
  1187.           if (jmpbuf) {
  1188.                /* HookEntryInt‚̐ݒè‚ɐ§Œä‚ªˆÚ‚é */
  1189.                bios_longjmp(jmpbuf);
  1190.                v0 = 1;
  1191.                PC = reg.r[31];
  1192.                         hw_write32(0x1f801070,0xFFFFFFFF);
  1193.           } else {
  1194.                interrupt_handler();
  1195.                PC = EPC;
  1196.                SR = (SR & ~0xf)| ((SR>>2)&0xf); /* rfe */
  1197.           }
  1198.           break;
  1199.      case E_Sys:
  1200.           switch(reg.r[4]) {
  1201.           case 1: SR &= ~0x404; PC = EPC+4; break;
  1202.           case 2: SR |=  0x404; PC = EPC+4; break;
  1203.           default: return -1;
  1204.           }
  1205.           SR = (SR & ~0xf)| ((SR>>2)&0xf); /* rfe */
  1206.           break;
  1207.      default:
  1208.           return -1;
  1209.      }
  1210.  
  1211.      return 0;
  1212. }
  1213.  
  1214. /*
  1215.      FONTX format
  1216.  
  1217.      idx  siz
  1218.      0    6    id   "FONTX"
  1219.      6    8    name
  1220.      14   1    width
  1221.      15   1    height
  1222.      16   1    type (0=ANK 1=Japanese)
  1223. ANK:
  1224.      17        font data (0x00-0xff)
  1225.  
  1226. Japanese:
  1227.      17   1    Number of code table
  1228.      18   2    start of code
  1229.      20   2    end of code
  1230.      .
  1231.      .
  1232.      18+N*4    font data
  1233. */
  1234.  
  1235. void *fileload(char *file,void *buf)
  1236. {
  1237.      FILE *fp;
  1238.      int fsize;
  1239.  
  1240.      fp = fopen(file,"rb");
  1241.      if (fp==NULL) return NULL;
  1242.      fseek(fp,0,SEEK_END);
  1243.      fsize = ftell(fp);
  1244.      fseek(fp,0,SEEK_SET);
  1245.      if (buf!=NULL || (buf = malloc(fsize))!=NULL) {
  1246.           fread(buf,1,fsize,fp);
  1247.      }
  1248.      fclose(fp);
  1249.      return buf;
  1250. }
  1251.  
  1252. static char *fontfile = "JPNZN16X.X11";
  1253.  
  1254. int bios_init(void)
  1255. {
  1256.      /* font load at rom area */
  1257.      font = (void*)(rom+0x20000);
  1258.      fileload(fontfile,font);
  1259.         return 0;
  1260. }